// ApplicationDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Application.h"
#include "ApplicationDlg.h"
#include "UPDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

bool ALongRightProcessProc(const CUP_DIALOG_USER_PROC_DATA* pCUPDUPData);
bool ALongWrongProcessProc(const CUP_DIALOG_USER_PROC_DATA* pCUPDUPData);

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CApplicationDlg dialog

CApplicationDlg::CApplicationDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CApplicationDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CApplicationDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CApplicationDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CApplicationDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CApplicationDlg, CDialog)
	//{{AFX_MSG_MAP(CApplicationDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDOK, OnBnClickedOk)
	ON_BN_CLICKED(IDOK2, OnBnClickedOk2)
	ON_BN_CLICKED(IDC_CUSTOMTEMPLATEBUTTON1, OnBnClickedCustomTemplate)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CApplicationDlg message handlers

BOOL CApplicationDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CApplicationDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CApplicationDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CApplicationDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CApplicationDlg::OnBnClickedOk()
{
	int nData = 0;

	CUPDialog	Dlg(this->GetSafeHwnd(),ALongRightProcessProc,&nData);

	INT_PTR nResult = Dlg.DoModal();

	if(nResult != IDOK)
	{
		if(!HIWORD(nResult))
			MessageBox(_T("Some Error Occured !!"));
		if(HIWORD(nResult) == 1)
			MessageBox(_T("User cancelled the lengthy operation !!"));
	}

	if(nResult == IDOK)	ASSERT(nData == 100);
}

bool ALongRightProcessProc(const CUP_DIALOG_USER_PROC_DATA* pCUPDUPData)
{
	int* pnCount = (int*)pCUPDUPData->GetAppData();

	pCUPDUPData->SetProgress(_T("Counting.."),0);

	while(pCUPDUPData->ShouldTerminate()== false && *pnCount != 100)
	{
		TCHAR szProgress[128];
		_stprintf(szProgress,_T("Counting..%d"),*pnCount);

		pCUPDUPData->SetProgress(*pnCount);			//Set Progress Bar Alone
		pCUPDUPData->SetProgress(szProgress);		//Set Progress Text Alone

		*pnCount = *pnCount + 1;

		if(*pnCount == 90) // If we have reached critical 90% progress, then how about disabling the Cancel button for the remaining 10%
		{
			pCUPDUPData->AllowCancel(false); 
			pCUPDUPData->SetDialogCaption(_T("Almost there...Finishing.."));
		}

		Sleep(100);
	}

	pCUPDUPData->SetProgress(_T("Done !!"),100);	//Set Both Progress Text and Bar

	return true;	// Return true to indicate everything has completed successfully
}

bool ALongWrongProcessProc(const CUP_DIALOG_USER_PROC_DATA* pCUPDUPData)
{
	int* pnCount = (int*)pCUPDUPData->GetAppData();

	pCUPDUPData->SetProgress(_T("Counting.."),0);

	while(pCUPDUPData->ShouldTerminate()== false && *pnCount < 48)
	{
		TCHAR szProgress[128];
		_stprintf(szProgress,_T("Counting..%d"),*pnCount);

		pCUPDUPData->SetProgress(*pnCount);			//Set Progress Bar Alone
		pCUPDUPData->SetProgress(szProgress);		//Set Progress Text Alone

		*pnCount = *pnCount + 1;

		Sleep(100);
	}

	return false;		//Simulate something Wrong by returning false
}

void CApplicationDlg::OnBnClickedOk2()
{
	int nData = 0;

	CUPDialog	Dlg(this->GetSafeHwnd(),ALongWrongProcessProc,&nData,_T("Waiting For Some Error To Occur .."),false);

	INT_PTR nResult = Dlg.DoModal();

	if(nResult != IDOK)
		if(!HIWORD(nResult))
			MessageBox(_T("This is Simulated Error : Place Your Error Message Here !!"),_T("Got the Error !!"));
}

// To use a custom dialog template with additional controls, override the CUPDialog::OnMessage() function
// However, note that not all messages get routed to OnMessage(). Only those that arrive after WM_INITDIALOG are routed.
class MyDlg : public CUPDialog
{
public :
	MyDlg(HWND hParentWnd,LP_CUPDIALOG_USERPROC lpUserProc,LPVOID lpUserProcParam,LPCTSTR lpszDlgTitle=_T("Please Wait.."),bool bAllowCancel=true)
	: CUPDialog(hParentWnd, lpUserProc, lpUserProcParam, lpszDlgTitle, bAllowCancel)
	{
	}
	virtual INT_PTR OnMessage(HWND hDlg,UINT Message,WPARAM wParam,LPARAM lParam, BOOL bProcessed)
	{
		switch(Message)
		{
		case WM_INITDIALOG:
			{
				SendMessage(GetDlgItem(hDlg, IDC_SLIDER1), TBM_SETRANGE, 0 , MAKELONG(0, 25));
				return TRUE;
			}		
		case WM_HSCROLL: // Take care of the Slider control here
			{
				switch(LOWORD(wParam))
				{
				case TB_ENDTRACK:
				case TB_THUMBTRACK:
					{
						int nPos = SendMessage(GetDlgItem(hDlg, IDC_SLIDER1), TBM_GETPOS, 0 , 0);

						TCHAR sz[16];
						_stprintf(sz, _T("%c, %c"), nPos + 'a', nPos + 'A');
						SetDlgItemText(hDlg, IDC_SLIDERTEXT, sz);

						// Lets enable the additional cancel button if the slider has gone above 13
						EnableWindow(GetDlgItem(hDlg, IDC_MYCANCELBUTTON), nPos >= 13 ? true : false);
						return TRUE;
					}
				}
				break;
			}

		case WM_COMMAND:
			{
				// we can the PROGRESSTHREADDATA::WM_CANCELPROGRESSTHREAD message anytime to shut down the progress dialog
				if(IDC_MYCANCELBUTTON == LOWORD(wParam))
				{
					SendMessage(hDlg,PROGRESS_THREAD_DATA::WM_CANCELPROGRESSTHREAD,0,0);
					return TRUE;
				}
				break;
			}
		}
		return FALSE; // Return false to continue any Default processing
	}
};



void CApplicationDlg::OnBnClickedCustomTemplate()
{
	int nData = 0;

	MyDlg Dlg(this->GetSafeHwnd(),ALongRightProcessProc,&nData);

	// Use My custom dialog template
	Dlg.SetDialogTemplate(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDD_CUSTOMPROGRESSDIALOG), IDC_STATIC, IDC_PROGRESS1, IDC_CANCEL); 

	INT_PTR nResult = Dlg.DoModal();

	if(nResult != IDOK)
	{
		if(!HIWORD(nResult))
			MessageBox(_T("Some Error Occured !!"));
		if(HIWORD(nResult) == 1)
			MessageBox(_T("User cancelled the lengthy operation !!"));
	}

	if(nResult == IDOK)	ASSERT(nData == 100);
}